/*
 * @Author: ljc
 * @Date: 2023-04-27 13:26:58
 * @LastEditors: LiSong
 * @LastEditTime: 2024-08-14 17:03:49
 * @Description: 关于文件工具方法
 *
 */
import router from '/@/router';
// 文件预览类型
export const fileType = {
    jpg: 'image/jpg',
    jpeg: 'image/jpeg',
    png: 'image/png',
    gif: 'image/gif',
    mp3: 'audio/mpeg',
    svg: 'image/svg+xml',
    text: 'text/plain',
    bmp: 'image/bmp',

    zip: 'application/zip',
    rar: 'application/x-rar-compressed',
    rar: 'application/octet-stream',

    pdf: 'application/pdf',
    doc: 'application/msword',
    docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    xls: "application/vnd.ms-excel",
    xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    ppt: 'application/vnd.ms-powerpoint',
    pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    excel: 'application/vnd.ms-excel',
    
    avi: 'video/x-msvideo',
    mpeg: 'video/mpeg',
    
    xml: 'text/xml',
    json: 'application/json',
    jsonld: 'application/ld+json',
    jar: 'application/java-archive',

    js: 'text/javascript',
    css: 'text/css',
    htm: 'text/html',
    html: 'text/html',
}

// 文件类型定义
export const FILE_TYPE_ENUM = fileType

/**
 * 文件下载
 *
 * @param {Object} options 配置参数
 * @returns {Object} 
 * data: 文件流 
 * fileName: 文件名(有值不需要从请求头拿)
 * type: 文件类型
 * res: 后台返回结果
 */
export function dowloadFile(data, fileName = "", type, res = {}) {
    let blob = new Blob([data], { type });
    const { size } = blob;
    if (size > 0 && !fileName && res) {
        const { headers } = res
        let contentDisposition = headers["content-disposition"];
        let targetKey = ";filename=";
        let targetKeyLen = targetKey.length;
        let contentLen = contentDisposition.length;
        let startIndex = contentDisposition.indexOf(targetKey) + targetKeyLen;
        let endIndex = contentLen;
        fileName = decodeURI(contentDisposition.substring(startIndex, endIndex));
    }
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {
        let objectUrl = (window.URL || window.webkitURL).createObjectURL(blob);
        let downFile = document.createElement("a");
        downFile.style.display = "none";
        downFile.href = objectUrl;
        downFile.download = fileName; // 下载后文件名
        document.body.appendChild(downFile);
        downFile.click();
        document.body.removeChild(downFile); // 下载完成移除元素 // window.location.href = objectUrl
        window.URL.revokeObjectURL(objectUrl); // 只要映射存在，Blob就不能进行垃圾回收，因此一旦不再需要引用，就必须小心撤销URL，释放掉blob对象。
    }
}
/**
 * 下载文件，根据文件响应流
 * 
 * @param {Object} res 请求的响应
 */
export function dowloadFileByStream(res, fileName) {
  const blob = new Blob([res.data], { type: res.data.type })
  console.log('blob', blob)
  const { size } = blob;
  if (size > 0) {
    const { headers } = res
    console.log('headers', headers)
    let contentDisposition = headers["content-disposition"];
    let targetKey = ";filename=";
    let targetKeyLen = targetKey.length;
    let contentLen = contentDisposition.length;
    let startIndex = contentDisposition.indexOf(targetKey) + targetKeyLen;
    let endIndex = contentLen;
    let finalFilename = fileName || decodeURI(contentDisposition.substring(startIndex, endIndex));
    if ('download' in document.createElement('a')) {
      const aLink = document.createElement('a');
      aLink.download = finalFilename
      aLink.style.display = 'none'
      aLink.href = window.URL.createObjectURL(blob);
      document.body.appendChild(aLink)
      aLink.click()
      window.URL.revokeObjectURL(aLink.href)
      document.body.removeChild(aLink)
    } else {
      navigator.msSaveBlob(blob, finalFilename)
    }
  } else {
    console.error("下载失败，文件不能为空，请重试！")
  }
}
// 文件预览
export function previewFile(data, type) {
    let blob = new Blob([data], { type });
    let url = (window.URL || window.webkitURL).createObjectURL(blob)
    return url
}
/**
 * 打开新的窗口
 * 
 * @param {String} url 地址
 * @param {String} title 标题
 * @param {Boolean} isOnline 是否使用在线预览组件
 * @param {String} fileSuffix 文件后缀名，例如：pdf, jpg
 */
export function openNewWindow(url, title, isOnline=false, fileSuffix) {
  const imgSuffix = ['jpeg', 'jpg', 'png',  'gif', 'bmp']
  if (isOnline) {
    if (fileSuffix && imgSuffix.includes(fileSuffix)) {
      const win = window.open(url, "_blank")
      if (win) win.document.title = title
    } else {
      const urls = router.resolve({
        name: 'previewFile',
        params: { id: url }
      })
      window.open(urls.href, '_blank')
    }
  } else {
    const win = window.open(url, "_blank")
    if (win) win.document.title = title
  }
}
/**
 * 将文件数据转换为Blob Url
 * 
 * @param {Object} data 
 * @param {String} type 
 * @returns BolbURL
 */
export function convertBlobURL(data, type) {
  let blob = new Blob([data], { type });
  let url = (window.URL || window.webkitURL).createObjectURL(blob)
  return url
}
/**
 * 获取文件后缀名称
 * 
 * @param {String} fileName 文件名称
 * @returns {String} 文件后缀
 */
export function getFileSuffix (fileName) {
  return fileName.slice(fileName.lastIndexOf('.') + 1).toLowerCase()
}
/**
 * 根据文件类型获取文件后缀名称
 * 
 * @param {String} fileType 文件类型
 * @returns {String} 文件后缀
 */
export function getFileSuffixByType (fileType) {
  let fileSuffix = ''
  for (let key in FILE_TYPE_ENUM) {
    let value = FILE_TYPE_ENUM[key]
    if (value === fileType) {
      fileSuffix = key
      break
    }
  }
  return fileSuffix
}
/**
 * 校验文件是否支持预览
 * 
 * @param {String} fileSuffix 文件的后缀
 * @returns {Boolean} true-支持 false-不支持
 */
export function isSupportPreview(fileSuffix) {
  const supportTypes = [
    'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pdf',
    'jpeg', 'jpg', 'png',  'gif', 'bmp'
  ]
  if (supportTypes.includes(fileSuffix.toLowerCase())) {
    return true
  } else {
    return false
  }
}
/**
 * 获取预览文件的文件类型
 *
 * @param {String} fileSuffix 文件后缀
 * @returns {String} 文件类型
 */
export function getPreviewFileType(fileSuffix) {
  fileSuffix = fileSuffix.toLowerCase()
  const pdfSupportTypes = [
    'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pdf',
  ]
  let type = ''
  if (pdfSupportTypes.includes(fileSuffix)) {
    type = FILE_TYPE_ENUM.pdf
  } else {
    type = FILE_TYPE_ENUM[fileSuffix]
  }
  return type
}
/**
 * 文件大小格式化显示携带单位
 *
 * @param {Number} size 文件大小
 * @returns {String} 转换后的内容
 * size: 是默认是kb
 */
export function formatDataFileSize(size) {
    size = size * 1024.00
    if (!size)
        return "";
    var num = 1024.00
    if (size < num)
        return size + "B";
    if (size < Math.pow(num, 2))
        return (size / num).toFixed(2) + "KB"; //kb
    if (size < Math.pow(num, 3))
        return (size / Math.pow(num, 2)).toFixed(2) + "M"; //M
    if (size < Math.pow(num, 4))
        return (size / Math.pow(num, 3)).toFixed(2) + "G"; //G
    return (size / Math.pow(num, 4)).toFixed(2) + "T"; //T
}

export default {
  dowloadFile,
  dowloadFileByStream,
  previewFile,
  openNewWindow,
  getFileSuffix,
  convertBlobURL,
  isSupportPreview,
  formatDataFileSize,
  getPreviewFileType,
  getFileSuffixByType
}